package com.freak.httpmanager.log;

import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.orhanobut.logger.AndroidLogAdapter;
import com.orhanobut.logger.FormatStrategy;
import com.orhanobut.logger.LogAdapter;
import com.orhanobut.logger.LogStrategy;
import com.orhanobut.logger.Logger;
import com.orhanobut.logger.PrettyFormatStrategy;

/**
 * Log日志工具，封装logger
 *
 * @author freak
 * @date 2022/09/12
 */
public class LogUtil {

    public static void d(String message) {
        Logger.d(message);
    }

    public static void d(Object message) {
        Logger.d(message);
    }

    public static void d(@NonNull String message, @Nullable Object... args) {
        Logger.d(message, args);
    }

    public static void e(String message) {
        Logger.e(message);
    }

    public static void e(String message, Throwable e) {
        Logger.e(e, message);
    }

    public static void e(@Nullable Throwable throwable, @NonNull String message, @Nullable Object... args) {
        Logger.e(throwable, message, args);
    }

    public static void i(String message) {
        Logger.i(message);
    }

    public static void v(@NonNull String message, @Nullable Object... args) {
        Logger.v(message, args);
    }

    public static void w(String message, Throwable e) {
        String info = e != null ? e.toString() : "null";
        Logger.w(message + "：" + info);
    }

    public static void wtf(@NonNull String message, @Nullable Object... args) {
        Logger.wtf(message, args);
    }

    public static void json(String json) {
        Logger.json(json);
    }

    public static void xml(@Nullable String xml) {
        Logger.xml(xml);
    }

    public static final class Builder {
        private PrettyFormatStrategy.Builder mFormatStrategyBuilder;
        private String mTagName;
        private int mMethodCount;
        private int mMethodOffset;
        private boolean mIsShowThreadInfo;
        private boolean mIsPrintLog;
        private LogStrategy mLogStrategy;
        private LogAdapter mLogAdapter;

        /**
         * 构造Builder
         */
        public Builder() {
            mFormatStrategyBuilder = PrettyFormatStrategy.newBuilder();
        }

        /**
         * （可选）每个日志的全局标记。默认PRETTY_LOGGER .build
         *
         * @param mTagName tag
         * @return Builder
         */
        public Builder setTagName(String mTagName) {
            this.mTagName = mTagName;
            return this;
        }

        /**
         * （可选）要显示的方法行数。默认值2
         *
         * @param mMethodCount 打印的方法行数
         * @return Builder
         */
        public Builder setMethodCount(int mMethodCount) {
            this.mMethodCount = mMethodCount;
            return this;
        }

        /**
         * （可选）隐藏内部方法调用到偏移量。默认值5
         *
         * @param mMethodOffset 偏移量
         * @return Builder
         */
        public Builder setMethodOffset(int mMethodOffset) {
            this.mMethodOffset = mMethodOffset;
            return this;
        }

        /**
         * （可选）更改要打印的日志策略。默认LogCat
         *
         * @param mLogStrategy 日志策略，传入LogStrategy的实现类，默认LogCat
         * @return Builder
         */
        public Builder setLogStrategy(LogStrategy mLogStrategy) {
            this.mLogStrategy = mLogStrategy;
            return this;
        }

        /**
         * （可选）是否显示线程信息。默认值true
         *
         * @param mIsShowThreadInfo true：显示 false：不显示
         * @return Builder
         */
        public Builder setIsShowThreadInfo(boolean mIsShowThreadInfo) {
            this.mIsShowThreadInfo = mIsShowThreadInfo;
            return this;
        }

        /**
         * 是否打印日志
         *
         * @param mIsPrintLog true：打印 false：不打印
         * @return Builder
         */
        public Builder setIsPrintLog(boolean mIsPrintLog) {
            this.mIsPrintLog = mIsPrintLog;
            return this;
        }

        /**
         * 设置自定义日志Adapter
         * 默认AndroidLogAdapter，此Adapter与mIsPrintLog一起使用
         *
         * @param logAdapter LogAdapter的实现类
         * @return Builder
         */
        public Builder setLogAdapter(LogAdapter logAdapter) {
            mLogAdapter = logAdapter;
            return this;
        }

        public void build() {
            mFormatStrategyBuilder.showThreadInfo(mIsShowThreadInfo);
            if (mMethodCount != 0) {
                mFormatStrategyBuilder.methodCount(mMethodCount);
            }
            if (mMethodOffset != 0) {
                mFormatStrategyBuilder.methodOffset(mMethodOffset);
            }
            if (mLogStrategy != null) {
                mFormatStrategyBuilder.logStrategy(mLogStrategy);
            }
            if (!TextUtils.isEmpty(mTagName)) {
                mFormatStrategyBuilder.tag(mTagName);
            }
            FormatStrategy mFormatStrategy = mFormatStrategyBuilder.build();
            if (mLogAdapter != null) {
                Logger.addLogAdapter(mLogAdapter);
            } else {
                Logger.addLogAdapter(new AndroidLogAdapter(mFormatStrategy) {
                    @Override
                    public boolean isLoggable(int priority, @Nullable String tag) {
                        return mIsPrintLog;
                    }
                });
            }
        }
    }
}
